/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package reportcenter.report.ui;

import reportcenter.report.ui.AdminReportTable;
import reportcenter.report.ui.AdminReportPropertiesDialog;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.FilterList;
import ca.odell.glazedlists.GlazedLists;
import ca.odell.glazedlists.TextFilterator;
import ca.odell.glazedlists.swing.TextComponentMatcherEditor;
import java.awt.BorderLayout;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import org.springframework.binding.value.ValueModel;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.richclient.application.PageComponentContext;
import org.springframework.richclient.application.event.LifecycleApplicationEvent;
import org.springframework.richclient.application.support.AbstractView;
import org.springframework.richclient.command.ActionCommand;
import org.springframework.richclient.command.ActionCommandExecutor;
import org.springframework.richclient.command.CommandGroup;
import org.springframework.richclient.command.GuardedActionCommandExecutor;
import org.springframework.richclient.command.support.AbstractActionCommandExecutor;
import org.springframework.richclient.command.support.GlobalCommandIds;
import org.springframework.richclient.dialog.ConfirmationDialog;
import org.springframework.richclient.list.ListSelectionValueModelAdapter;
import org.springframework.richclient.list.ListSingleSelectionGuard;
import reportcenter.auth.business.RolesDao;
import reportcenter.report.business.AdminReportDao;
import reportcenter.datasource.business.DataSourceDao;
import reportcenter.recover.TesteBackup;
import reportcenter.report.dominio.report.Report;
import reportcenter.report.support.exporter.XlsExporterExecutor;
import reportcenter.support.threading.Job;
import reportcenter.support.threading.JobListener;
import reportcenter.support.threading.WorkerJob;
import spin.Spin;

/**
 *
 * @author renan_luz
 */
public class AdminReportView extends AbstractView implements ApplicationListener,JobListener {

    private AdminReportTable adminReportTable;
    private AdminReportDao adminReportDao;
    private DataSourceDao dataSourceDao;
    private RolesDao roleDao;

    public RolesDao getRoleDao() {
        return roleDao;
    }

    public void setRoleDao(RolesDao roleDao) {
        this.roleDao = roleDao;
    }

    public DataSourceDao getDataSourceDao() {
        return dataSourceDao;
    }

    public void setDataSourceDao(DataSourceDao dataSourceDao) {
        this.dataSourceDao = dataSourceDao;
    }

    public AdminReportDao getAdminReportDao() {
        return adminReportDao;
    }

    public void setAdminReportDao(AdminReportDao adminReportDao) {
        this.adminReportDao = adminReportDao;
    }
    /**
     * Campo texto que permite filtrar o conteúdo da tabela.
     */
    private JTextField filterField;

    @Override
    protected JComponent createControl() {

        
//        ApplicationSecurityManager sm = (ApplicationSecurityManager) getService(ApplicationSecurityManager.class);
//        
//        SecurityContextHolder.getContext().getAuthentication().getAuthorities();
//          
//        if (sm.isUserInRole("ROLE_SUPREME")) {

            //Painel do filtro
            JPanel filterPanel = new JPanel(new BorderLayout());
            //Label do filtro
            JLabel filterLabel = getComponentFactory().createLabel("adminReportFilter.label");
            filterPanel.add(filterLabel, BorderLayout.WEST);

            String tip = getMessage("adminReportFilter.caption");
            filterField = getComponentFactory().createTextField();
            filterField.setToolTipText(tip);
            filterPanel.add(filterField, BorderLayout.CENTER);
            filterPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

            //instancia tabela de relatórios
            adminReportTable = new AdminReportTableFactory().createAdminReportTable();

            JPanel view = new JPanel(new BorderLayout());
            JScrollPane sp = getComponentFactory().createScrollPane(adminReportTable.getControl());
            view.add(filterPanel, BorderLayout.NORTH);
            view.add(sp, BorderLayout.CENTER);

            return view;
//        } else {
//            return new UserReportView().createControl();
//        }
    }

    /**
     * Prepara a tabela contendo os objetos do relatório. A tabela fornece conjunto de funcionalidades presentes nessa View.
     * Na chamada desse método o método set {@link #setReportTable(ReportTable)} já terá sido invocado como parte do contexto
     * de criação do bean.
     */
    private class AdminReportTableFactory {

        public AdminReportTable createAdminReportTable() {
            AdminReportTable adminReportTable = new AdminReportTable(adminReportDao);

            adminReportTable.setDoubleClickHandler(exportToXlsExecutor);

            //Evento de filtro
            EventList baseList = adminReportTable.getBaseEventList();
//            TextFilterator filterator = GlazedLists.textFilterator(new String[]{"title", "subtitle", "query"});
            TextFilterator filterator = GlazedLists.textFilterator(new String[]{"title", "subtitle", "idRole.roleName"});
            FilterList filterList = new FilterList(baseList, new TextComponentMatcherEditor(filterField, filterator));
            adminReportTable.setFinalEventList(filterList);

            //Configuração do menu de popup
            CommandGroup popup = new CommandGroup();
//            popup.add((ActionCommand) getWindowCommandManager().getCommand("showReportCommand", ActionCommand.class));

            CommandGroup exportGroup = new CommandGroup();
            exportGroup.setLabel("Exportar Relatório");
            exportGroup.add((ActionCommand) getWindowCommandManager().getCommand("exportToPdfCommand", ActionCommand.class));
            exportGroup.add((ActionCommand) getWindowCommandManager().getCommand("exportToXlsCommand", ActionCommand.class));
            exportGroup.add((ActionCommand) getWindowCommandManager().getCommand("exportToOdtCommand", ActionCommand.class));
            popup.add(exportGroup);

            popup.addSeparator();
            popup.add((ActionCommand) getWindowCommandManager().getCommand("propertiesCommand", ActionCommand.class));
            popup.add((ActionCommand) getWindowCommandManager().getCommand("deleteCommand", ActionCommand.class));
            popup.addSeparator();
            popup.add((ActionCommand) getWindowCommandManager().getCommand("columRenameCommand", ActionCommand.class));

            adminReportTable.setPopupCommandGroup(popup);

            adminReportTable.setStatusBar(getStatusBar());

            ValueModel selectionHolder = new ListSelectionValueModelAdapter(adminReportTable.getSelectionModel());
            new ListSingleSelectionGuard(selectionHolder, propExecutor);
            new ListSingleSelectionGuard(selectionHolder, delExecutor);
//            new ListSingleSelectionGuard(selectionHolder, showReportExecutor);
            new ListSingleSelectionGuard(selectionHolder, exportToPdfExecutor);
            new ListSingleSelectionGuard(selectionHolder, exportToXlsExecutor);
            new ListSingleSelectionGuard(selectionHolder, exportToOdtExecutor);
            new ListSingleSelectionGuard(selectionHolder, columRenameExecutor);


            return adminReportTable;
        }
    }

    public void onApplicationEvent(ApplicationEvent e) {
        adminReportTable.onApplicationEvent(e);
    }
    private ActionCommandExecutor newExecutor = new NewExecutor();

    private class NewExecutor implements ActionCommandExecutor {

        public void execute() {
            new AdminReportPropertiesDialog(getAdminReportDao()).showDialog();
        }
    }
    private GuardedActionCommandExecutor propExecutor = new PropExecutor();

    private class PropExecutor extends AbstractActionCommandExecutor {

        public void execute() {
            new AdminReportPropertiesDialog(adminReportTable.getSelectedReport(), getAdminReportDao()).showDialog();
        }
    }
    private GuardedActionCommandExecutor delExecutor = new DelExecutor();

    private class DelExecutor extends AbstractActionCommandExecutor {

        public void execute() {
            // We know exactly one contact will be selected at this time because
            // of the guards put in place in prepareTable.
            final Report report = adminReportTable.getSelectedReport();
            // Query the user to be sure they want to do this
            String title = getMessage("AdminReportView.confirmDelete.title");
            String message = getMessage("AdminReportView.confirmDelete.message");
            ConfirmationDialog dlg = new ConfirmationDialog(title, message) {

                protected void onConfirm() {
                    // Delete the object from the persistent store.
                    getAdminReportDao().delete(report);
                    // And notify the rest of the application of the change
                    getApplicationContext().publishEvent(
                            new LifecycleApplicationEvent(LifecycleApplicationEvent.DELETED, report));
                }
            };
            dlg.showDialog();
        }
    }
    private GuardedActionCommandExecutor showReportExecutor = new ShowReportExecutor();

    private class ShowReportExecutor extends AbstractActionCommandExecutor {

        public void execute() {
            JOptionPane.showMessageDialog(null, "Visualizador de Relatório: disponível em breve!");
        }
    }
    private GuardedActionCommandExecutor exportToPdfExecutor = new ExportToPdfExecutor();

    private class ExportToPdfExecutor extends AbstractActionCommandExecutor {

        public void execute() {
            WorkerJob job = (WorkerJob) Spin.off(new Job());

            // use the Spin.over functionality
            job.addJobListener((JobListener) Spin.over(AdminReportView.this));

            // execute the job
            job.run();
            
            
            JOptionPane.showMessageDialog(null, "Exportação PDF: disponível em breve!");
        }
    }
    private GuardedActionCommandExecutor exportToXlsExecutor = new ExportToXlsExecutor();

    private class ExportToXlsExecutor extends AbstractActionCommandExecutor {

        public void execute() {
            
            final Report report = adminReportTable.getSelectedReport();
            WorkerJob job = (WorkerJob) Spin.off(new XlsExporterExecutor(report));

            // use the Spin.over functionality
            job.addJobListener((JobListener) Spin.over(AdminReportView.this));

            // execute the job
            job.run();
        }
    }
    private GuardedActionCommandExecutor exportToOdtExecutor = new ExportToOdtExecutor();

    private class ExportToOdtExecutor extends AbstractActionCommandExecutor {

        public void execute() {
//            TesteBackup.backUpDatabase();
//            JOptionPane.showMessageDialog(null, "Exportação ODT: disponível em breve!");
        }
    }
        
    private ActionCommandExecutor refreshExecutor = new RefreshExecutor();

    private class RefreshExecutor implements ActionCommandExecutor {

        public void execute() {
            adminReportTable.refreshTable();
        }
    }
    
    private GuardedActionCommandExecutor columRenameExecutor = new ColumRenameExecutor();

    private class ColumRenameExecutor extends AbstractActionCommandExecutor {

        public void execute() {
            JOptionPane.showMessageDialog(null, "Renomear Colunas");
        }
    }

    /**
     * Registra os executores de comando com os comandos associados a eles(comandos registrados em "richclient-application-context.xml"). 
     * Esse método é invocado pelo framework para tornar a view(ex: botão deletar) visível.
     */
    protected void registerLocalCommandExecutors(PageComponentContext context) {
        context.register("newCommand", newExecutor);
        context.register(GlobalCommandIds.PROPERTIES, propExecutor);
        context.register(GlobalCommandIds.DELETE, delExecutor);
//        context.register("showReportCommand", showReportExecutor);
        context.register("exportToPdfCommand", exportToPdfExecutor);
        context.register("exportToXlsCommand", exportToXlsExecutor);
        context.register("exportToOdtCommand", exportToOdtExecutor);
        context.register("refreshCommand", refreshExecutor);
        context.register("columRenameCommand", columRenameExecutor);
        
    }

    
    public void start() {
        getStatusBar().setMessage("Iniciando processo de geração do relatório..."); // And/or other Swing stuff
        getStatusBar().getProgressMonitor().taskStarted("Inicializando", -1);
    }

    public void end() {
//        getStatusBar().setMessage("Geração de relatório finalizada!"); // And/or other Swing stuff
        getStatusBar().getProgressMonitor().done();
    }

    public void progress(int percent) {
//        getStatusBar().setMessage(percent + "% completo"); // And/or other Swing stuff
        getStatusBar().getProgressMonitor().worked(percent); 
    }

    public void status(String msg) {
        getStatusBar().setMessage(msg);
    }

    
}
